package com.leemon.mall.security.filter;

import com.leemon.mall.security.token.AuthenticationTokenParser;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.util.StreamUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.Charset;

/**
 * @author limenglong
 * @create 2019-09-16 11:06
 * @desc 登录认证过滤器
 **/
public class LoginAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    @Autowired
    private AuthenticationTokenParser authenticationTokenParser;

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        if (!request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException(
                    "Authentication method not supported: " + request.getMethod());
        }

        //请求参数不限于username和password
        String requestBody = null;
        try {
            requestBody = StreamUtils.copyToString(request.getInputStream(), Charset.defaultCharset());
        } catch (IOException e) {
            e.printStackTrace();
        }

        if (StringUtils.isBlank(requestBody)) {
            throw new AuthenticationServiceException("无法获取输入信息");
        }

        //公共模块定制化，需要写通用接口
        AbstractAuthenticationToken authRequest = authenticationTokenParser.parse(requestBody);

        // Allow subclasses to set the "details" property
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));

        return this.getAuthenticationManager().authenticate(authRequest);

    }
}
